﻿using System;
using System.Collections.Generic;
using System.Windows;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using HYRElectric.Equipment;

namespace HYRElectric.PowerSystem
{
	public class EquipExchangeExternalHandler : IExternalEventHandler
	{
		public EquipExchangeExternalHandler(ExternalCommandData cmdDataIn)
		{
			this.cmdData = cmdDataIn;
			this.doc = cmdDataIn.Application.ActiveUIDocument.Document;
			this.m_dictEleMatchDbFamily = new Dictionary<FamilyInstance, EquipmentExchangeSetInfo>();
			this.m_dictExchangePairs = new Dictionary<FamilyInstance, ElementId>();
		}

		public void SetDetectDlg(ref DlgPanelSystemDetect dlgDetect)
		{
			this.m_dlgDetect = dlgDetect;
		}

		public void SetExchangeSetInfo(Dictionary<FamilyInstance, EquipmentExchangeSetInfo> dict, bool bRotateEquipment)
		{
			this.m_bRotateEquipment = bRotateEquipment;
			this.m_dictEleMatchDbFamily = dict;
		}

		public Request Request
		{
			get
			{
				return this.m_request;
			}
		}

		public Dictionary<FamilyInstance, ElementId> GetExchangePairs()
		{
			return this.m_dictExchangePairs;
		}

		public string GetName()
		{
			return "EquipmentExchange External Event";
		}

		public void Execute(UIApplication app)
		{
			Document document = app.ActiveUIDocument.Document;
			RequestId requestId = this.Request.Take();
			if (requestId == RequestId.None)
			{
				return;
			}
			if (requestId != RequestId.Exchange)
			{
				return;
			}
			this.Exchange();
		}

		private static Transform GetTransformForLinkDoc(Document curDoc, Document linkDoc)
		{
			IEnumerable<ElementId> enumerable = new FilteredElementCollector(curDoc).OfClass(typeof(RevitLinkInstance)).ToElementIds();
			RevitLinkInstance revitLinkInstance = null;
			foreach (ElementId elementId in enumerable)
			{
				Element element = curDoc.GetElement(elementId);
				if (!(element.GetType() != typeof(RevitLinkInstance)))
				{
					RevitLinkInstance revitLinkInstance2 = element as RevitLinkInstance;
					if (revitLinkInstance2 != null)
					{
						Document linkDocument = revitLinkInstance2.GetLinkDocument();
						if (linkDocument != null && linkDoc.PathName == linkDocument.PathName)
						{
							revitLinkInstance = revitLinkInstance2;
							break;
						}
					}
				}
			}
			if (revitLinkInstance == null)
			{
				return null;
			}
			return revitLinkInstance.GetTotalTransform();
		}

		public static XYZ TransformPoint(XYZ point, Transform transform)
		{
			double x = point.X;
			double y = point.Y;
			double z = point.Z;
			XYZ xyz = transform.get_Basis(0);
			XYZ xyz2 = transform.get_Basis(1);
			XYZ xyz3 = transform.get_Basis(2);
			XYZ origin = transform.Origin;
			double num = x * xyz.X + y * xyz2.X + z * xyz3.X + origin.X;
			double num2 = x * xyz.Y + y * xyz2.Y + z * xyz3.Y + origin.Y;
			double num3 = x * xyz.Z + y * xyz2.Z + z * xyz3.Z + origin.Z;
			return new XYZ(num, num2, num3);
		}

		public static void GetLinkEleCurDocLocation(ref XYZ ptBase, ref double dAngle, Document curDoc, FamilyInstance curEle)
		{
			dAngle = 0.0;
			ptBase = DlgPanelSystemDetect.GetElecEquipPositionInfo(ref dAngle, curEle);
			Transform transformForLinkDoc = EquipExchangeExternalHandler.GetTransformForLinkDoc(curDoc, curEle.Document);
			if (transformForLinkDoc != null)
			{
				ptBase = EquipExchangeExternalHandler.TransformPoint(ptBase, transformForLinkDoc);
			}
		}

		private void Exchange()
		{
			try
			{
				foreach (KeyValuePair<FamilyInstance, EquipmentExchangeSetInfo> keyValuePair in this.m_dictEleMatchDbFamily)
				{
					FamilyInstance key = keyValuePair.Key;
					EquipmentExchangeSetInfo value = keyValuePair.Value;
					EquipmentLayoutCmdEntry equipmentLayoutCmdEntry = new EquipmentLayoutCmdEntry(this.cmdData, value.EquipmentType);
					new EquipmentLayout(this.cmdData.Application.ActiveUIDocument, this.doc, value.DbFamilyObjectCur, null, equipmentLayoutCmdEntry.GetCategoryFilters()).GetFamilySymbol();
				}
				Transaction transaction = new Transaction(this.doc, "EquipmentExchange");
				transaction.Start();
				foreach (KeyValuePair<FamilyInstance, EquipmentExchangeSetInfo> keyValuePair2 in this.m_dictEleMatchDbFamily)
				{
					FamilyInstance key2 = keyValuePair2.Key;
					EquipmentExchangeSetInfo value2 = keyValuePair2.Value;
					double num = 0.0;
					XYZ xyz = null;
					EquipExchangeExternalHandler.GetLinkEleCurDocLocation(ref xyz, ref num, this.doc, key2);
					if (!this.m_bRotateEquipment)
					{
						num = 0.0;
					}
					EquipmentLayoutCmdEntry equipmentLayoutCmdEntry2 = new EquipmentLayoutCmdEntry(this.cmdData, value2.EquipmentType);
					EquipmentLayout equipmentLayout = new EquipmentLayout(this.cmdData.Application.ActiveUIDocument, this.doc, value2.DbFamilyObjectCur, null, equipmentLayoutCmdEntry2.GetCategoryFilters());
					FamilySymbol familySymbol = equipmentLayout.GetFamilySymbol();
					num *= 57.295779513082323;
					double num2 = xyz.Z - this.doc.ActiveView.GenLevel.Elevation;
					if (value2.DbFamilyObjectCur.Name.IndexOf("消火栓") >= 0)
					{
						num += 180.0;
					}
					FamilyInstance familyInstance = YJKRevitTools.LayFamilySymbol(this.doc, xyz, familySymbol, this.doc.ActiveView.GenLevel, num);
					if (familyInstance == null)
					{
						throw new Exception("布置设备出错。");
					}
					if (key2.Mirrored)
					{
						Plane plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(this.doc.ActiveView.ViewDirection, xyz);
						List<ElementId> list = new List<ElementId>();
						list.Add(familyInstance.Id);
						RevitVersionFuncs.MirrorElements(this.doc, list, plane, false);
					}
					equipmentLayout.SetParametersValue(familyInstance, 0);
					Parameter parameter = familyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
					if (parameter != null)
					{
						parameter.Set(num2);
					}
					this.m_dictExchangePairs.Add(key2, familyInstance.Id);
				}
				transaction.Commit();
				this.m_dlgDetect.SaveSelectInfo(this.m_dictExchangePairs);
				MessageBox.Show("图例替换完成");
			}
			catch (Exception)
			{
			}
		}

		private ExternalCommandData cmdData;

		private Document doc;

		private Dictionary<FamilyInstance, EquipmentExchangeSetInfo> m_dictEleMatchDbFamily;

		private bool m_bRotateEquipment = true;

		private DlgPanelSystemDetect m_dlgDetect;

		private Dictionary<FamilyInstance, ElementId> m_dictExchangePairs;

		private Request m_request = new Request();
	}
}
